package com.uzai.console.common.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

/**
 * 实现金额均匀随机分配红包金额
 * @author liuqi
 * @date 2023年01月29日 16:19
 */
public class RedEnvelope {

    static Scanner sc = new Scanner(System.in);

    /**
     * 拼手速红包金额算法(线段切割法)
     * 手速越快就大几率大红包
     * @param money
     * @param number
     */
    private static boolean LineSegmentCutting(double money, int number) {
        if (money <= 0 && number < 1) {
            return false;
        }
        double begin = 0; // 起始金额
        double end = money; // 最终金额
        double sum = 0; // 金额总数
        for (int i = 0; i < number - 1; i++) {
            double AmountOfTime = 0; // 次金额
            double amount = nextDouble(begin, end);
            AmountOfTime = amount - begin;
            System.out.println("提示：" + (i + 1) + "号用户领取到金额为" + format(AmountOfTime) + "元的红包！");
            sum += AmountOfTime;
            begin = amount;
        }
        sum += (end - begin);
        System.out.println("提示：" + number + "号用户领取到金额为" + format(end - begin) + "元的红包！");
        System.out.println("红包总金额验证：" + format(sum) + "元！");
        return true;
    }


    /**
     * 公平红包金额算法(二倍均值法)
     *
     * @param money
     * @param number
     * @return result
     */
    public static List<Double> doubleMeanMethod(double money, int number) {
        List<Double> result = new ArrayList<>();
        if (money <= 0 && number < 1) { // 红包金额以及数量不符合实际情况
            return null;
        }

        double begin = 0.00D; //起始金额
        double amount = 0.0; // 随机金额
        int remainingQty = number; // 红包剩余数量
        int times = 1; // 人次计数
        while (remainingQty > 1) {
            amount = nextDouble(begin, 2 * (money / remainingQty));
            //System.out.println("提示：" + times + "号用户领取到金额为" + format(amount) + "元的红包！");
            money -= amount; // 总金额减去已领取金额
            remainingQty--; // 红包数量自减
            times++; // 号码自增
            result.add(amount);
        }
        result.add(money);
        //System.out.println("提示：" + times + "号用户领取到金额为" + format(amount) + "元的红包！");
        return result;
    }

    /**
     * 保留两位小数
     *
     * @param value
     * @return
     */
    private static String format(double value) {
        return new java.text.DecimalFormat("0.00").format(value);
    }

    /**
     * 生成(min,max)的浮点数
     *
     * @param min
     * @param max
     * @return
     */
    private static double nextDouble(double min, double max) {
        return min + ((max - min) * new Random().nextDouble());
    }


    public static void main(String[] args) {

        System.out.print("请输入红包金额：");
        double money = sc.nextDouble();
        System.out.print("请设置红包个数：");
        int number = sc.nextInt();

        System.out.println("\n-------------均值红包-------------");
        List<Double> result1 =  doubleMeanMethod(money, number);
        Double sum1 = 0D;
        if (result1 != null) {
            for (int i = 0; i < result1.size(); i++) {
                sum1 = sum1 + result1.get(i);
                System.out.println("提示：" + i + 1 + "号用户领取到金额为" + format(result1.get(i)) + "元的红包！");
            }

            System.out.println("红包总金额验证：" + format(sum1) + "元！");

        }
    }

}
